package com.zzyl.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.json.JSONUtil;
import com.zzyl.dto.LoginDto;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.LoginUserMapper;
import com.zzyl.properties.AccessUrlsConfigProperties;
import com.zzyl.properties.JwtTokenManagerProperties;
import com.zzyl.service.LoginService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private LoginUserMapper loginUserMapper;
    @Autowired
    private JwtTokenManagerProperties jwtTokenManagerProperties;
    @Autowired
    private AccessUrlsConfigProperties accessUrlsConfigProperties;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public UserVo login(LoginDto loginDto) {
        //用户名查询用户数据
        UserVo userVo = loginUserMapper.queryUserByName(loginDto.getUsername());
        if(ObjectUtil.isEmpty(userVo)){
            throw new BaseException(BasicEnum.LOGIN_FAIL);
        }

        //判断用户是否被禁用
        if("1".equals(userVo.getDataState())){
            throw new BaseException(BasicEnum.ACCOUNT_DISABLED);
        }

        //验证密码是否正确
        String password = userVo.getPassword();
        boolean checkpw = BCrypt.checkpw(loginDto.getPassword(), password);
        if(!checkpw){
            throw new BaseException(BasicEnum.PASSWORD_ERROR);
        }
//授权——分配资源
        //授权-获取当前用户的资源列表
        List<String> urlList = loginUserMapper.queryResourceUrlListByUserId(userVo.getId());
        //授权-获取白名单列表
        List<String> publicAccessUrls = accessUrlsConfigProperties.getPublicAccessUrls();
        //用户能访问的全部资源列表
        urlList.addAll(publicAccessUrls);

        //jwt进行加密
        HashMap<String,Object> map = new HashMap<>();
        userVo.setPassword("");
        map.put("user",JSONUtil.toJsonStr(userVo));
        String token = JwtUtil.createJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(),
                jwtTokenManagerProperties.getTtl(),
                map);
        userVo.setUserToken(token);

        //授权-资源列表存储到 Radis
        redisTemplate.opsForValue().set("user:resourceurl:"+userVo.getId(),JSONUtil.toJsonStr(urlList),
                jwtTokenManagerProperties.getTtl()/1000, TimeUnit.SECONDS);

        return userVo;
    }
}
